package com.lingyun.financialmanagement.service.pojo;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lingyun.financialmanagement.dao.mapper.BillMapper;
import com.lingyun.financialmanagement.dao.mapper.BusinessTripMapper;
import com.lingyun.financialmanagement.dao.mapper.ProjectMapper;
import com.lingyun.financialmanagement.dao.mapper.UsersMapper;
import com.lingyun.financialmanagement.dao.pojo.BusinessTrip;
import com.lingyun.financialmanagement.dao.pojo.OperationLog;
import com.lingyun.financialmanagement.dao.pojo.Users;
import com.lingyun.financialmanagement.service.BusinessTripService;
import com.lingyun.financialmanagement.utils.ProjectUtils;
import com.lingyun.financialmanagement.utils.TokenGetUser;
import com.lingyun.financialmanagement.vo.ErrorCode;
import com.lingyun.financialmanagement.vo.Result;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class BusinessTripServiceImpl implements BusinessTripService {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private BusinessTripMapper businessTripMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Value("${redis.token.tokenAccountPrefix}")
    private String tokenAccountPrefix;
    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private BillMapper billMapper;
    @Autowired
    private OperationLogServiceImpl operationLogServiceImpl;

    @Override
    public Result selectByTokenBusinessTrip() {
        String token = request.getHeader("token");
        if (token == null){
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }

        String account = redisTemplate.opsForValue().get(tokenAccountPrefix + token);
        if (account == null || account.isEmpty()){
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }

        Users users = usersMapper.selectByAccount(account);
        if (users == null){
            return Result.fail(ErrorCode.USERS_NULL.getCode(), ErrorCode.USERS_NULL.getMsg());
        }

        QueryWrapper<BusinessTrip> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("users", users.getId());
        List<BusinessTrip> businessTrips = businessTripMapper.selectList(queryWrapper);
        return Result.success(businessTrips);
    }

    @Override
    public Result selectAllBusinessTrip() {
        List<BusinessTrip> businessTrips = businessTripMapper.selectList(null);
        return Result.success(businessTrips);
    }

    @Override
    public Result selectByAllPayMethodBusinessTrip() {
        QueryWrapper<BusinessTrip> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("payment_method", "verify_pay");
        List<BusinessTrip> businessTrips = businessTripMapper.selectList(queryWrapper);
        return Result.success(businessTrips);
    }

    @Override
    public Result selectByPayMethodBusinessTripToken() {
        String token = request.getHeader("token");
        String account = redisTemplate.opsForValue().get(tokenAccountPrefix + token);
        Users users = usersMapper.selectByAccount(account);
        if (users == null){
            return Result.fail(ErrorCode.USERS_NULL.getCode(), ErrorCode.USERS_NULL.getMsg());
        }
        QueryWrapper<BusinessTrip> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("users", users.getId());
        queryWrapper.eq("payment_method", "verify_pay");
        queryWrapper.orderByAsc("create_time");

        List<BusinessTrip> businessTrips = businessTripMapper.selectList(queryWrapper);
        return Result.success(businessTrips);
    }

    @Override
    @Transactional
    public Result addBusinessTrip(BusinessTrip businessTrip) {
        // 获取用户
        Result usersResult = TokenGetUser.getUsers(request, redisTemplate, tokenAccountPrefix, usersMapper);
        if (usersResult.getCode() != 200){
            return Result.fail(ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMsg());
        }
        Users users = (Users) usersResult.getData();
        // 设置用户
        businessTrip.setUsers(users.getId());
        int insert = 0;
        try{
            insert = businessTripMapper.insert(businessTrip);
        } catch (Exception e) {
            throw new RuntimeException(ErrorCode.INSERT_ERROR.getMsg());
        }
        if (insert == 0){
            throw new RuntimeException(ErrorCode.INSERT_ERROR.getMsg());
        }

        // 对项目做修改
        try {
            // 增加项目成本
            ProjectUtils.addWarehouseCost(businessTrip.getProject(),businessTrip.getPaymentMethod(), businessTrip.getCost(), projectMapper, businessTrip.getBill(), billMapper);

            // 增加项目税额
            ProjectUtils.addWarehouseTax(businessTrip, projectMapper, billMapper);
        } catch (Exception e) {
            throw new RuntimeException("增加价格错误");
        }

        // 记录日志
        Result result = operationLogServiceImpl.insertLog(request, new OperationLog(null, null, null, businessTrip.getId(), businessTrip.getProject(), "提交了差旅表单", null));
        if (result.getCode() != 200){
            throw new RuntimeException(result.getMsg());
        }

        return Result.success(businessTrip);
    }
}
